package common

import (
	"bytes"
	"crypto/aes"
	"crypto/cipher"
	"crypto/md5"
	"encoding/base64"
	"encoding/hex"
	"fmt"
	"log"
	"strings"
)

var dB_KEY []byte
var iV []byte

// 初始化加密数据
func InitSecretKey() {
	dB_KEY = []byte("ASDFGHJKLZXCVBNM")
	iV = []byte("QWERTYUIOPZXCVBN")
}

func pkcs7Padding(ciphertext []byte, blockSize int) []byte {
	padding := blockSize - len(ciphertext)%blockSize
	padtext := bytes.Repeat([]byte{byte(padding)}, padding)
	return append(ciphertext, padtext...)
}

func Encrypt(plaintext []byte, key []byte, iv []byte) ([]byte, error) {
	block, err := aes.NewCipher(key)
	if err != nil {
		return nil, err
	}
	plaintext = pkcs7Padding(plaintext, block.BlockSize())
	ciphertext := make([]byte, len(plaintext))
	mode := cipher.NewCBCEncrypter(block, iv)
	mode.CryptBlocks(ciphertext, plaintext)
	return ciphertext, nil
}

func Decrypt(ciphertext []byte, key []byte, iv []byte) ([]byte, error) {
	block, err := aes.NewCipher(key)
	if err != nil {
		return nil, err
	}
	plaintext := make([]byte, len(ciphertext))
	mode := cipher.NewCBCDecrypter(block, iv)
	mode.CryptBlocks(plaintext, ciphertext)

	// 移除PKCS#7填充
	padding := int(plaintext[len(plaintext)-1])
	if padding < 1 || padding > block.BlockSize() {
		return nil, fmt.Errorf("invalid padding")
	}
	plaintext = plaintext[:len(plaintext)-padding]
	return plaintext, nil
}

// md 加密
func Md5Hex(str string) string {
	hash5 := md5.New()
	hash5.Write([]byte(str))
	hashBytes := hash5.Sum(nil)
	return hex.EncodeToString(hashBytes)
}

// db 中数据加密
func DBEncrypt(originStr string) (string, error) {
	if len(originStr) == 0 {
		return originStr, nil
	}
	encrypt, err := Encrypt([]byte(originStr), dB_KEY, iV)
	return string(encrypt), err
}

// db 中数据解密
func DBDecrypt(originStr string) (string, error) {
	if len(originStr) == 0 {
		return originStr, nil
	}
	decrypt, err := Decrypt([]byte(originStr), dB_KEY, iV)
	return string(decrypt), err
}

// 解密配置文件
func ConfigDetailDecrypt(ymlKey string, originStr string, key []byte) string {
	if len(originStr) == 0 {
		return originStr
	}
	if strings.HasPrefix(originStr, "ENC(") && strings.Contains(originStr, ")") {
		homeSuffixStr := strings.Trim(originStr, "ENC(")
		lastSuffixStr := strings.Trim(homeSuffixStr, ")")
		decodeByte, _ := base64.StdEncoding.DecodeString(lastSuffixStr)
		decrypt, err := Decrypt(decodeByte, key, iV)
		if err != nil {
			log.Fatalf("配置 %s 的值解密失败, 请检查详细配置文件, 具体错误如下 %s", ymlKey, err)
		}
		return string(decrypt)
	}
	return originStr
}

// 加密配置文件  数据
func ConfigDetailEncrypt(originStr string) {
	if len(originStr) == 0 {
		log.Fatalf("需要加密的数据不能为空")
	}
	encrypt_str := "BasicProjectBOTS"
	encrypt, err := Encrypt([]byte(originStr), []byte(encrypt_str), iV)
	if err != nil {
		log.Fatalf("加密配置文件失败: %v", err)
	}
	encryptStr := base64.StdEncoding.EncodeToString(encrypt)
	fmt.Println("加密后的字符串（Base64）:", encryptStr)

	// 解密
	decodeByte, err := base64.StdEncoding.DecodeString(encryptStr)
	if err != nil {
		log.Fatalf("Base64 解码失败: %v", err)
	}
	decrypt, err := Decrypt(decodeByte, []byte(encrypt_str), iV)
	if err != nil {
		log.Fatalf("解密配置文件失败: %v", err)
	}
	fmt.Println("解密后的字符串:", string(decrypt))
}
